home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Tetris Light 1.0 / source / main.c < prev    next >
C/C++ Source or Header  |  1993-07-18  |  8KB  |  362 lines

  1. /**********************************************************************\
  2.  
  3. File:        main.c
  4.  
  5. Purpose:    This is the main module for the Tetris program.
  6.             
  7.  
  8. ``Tetris Light'' - a simple implementation of a Tetris game.
  9. Copyright (C) 1993 Hoylen Sue
  10.  
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 2 of the License, or
  14. (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; see the file COPYING.  If not, write to the
  23. Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  
  25. \**********************************************************************/
  26.  
  27. #include "local.h"
  28.  
  29. #include "alert.h"
  30. #include "controls.h"
  31. #include "game.h"
  32. #include "highscore.h"
  33. #include "windows.h"
  34. #include "menu_da.h"
  35. #include "env.h"
  36. #include "resources.h"
  37. #include "pref_file.h"
  38.  
  39. /*--------------------------------------------------------------------*/
  40.  
  41. /* Globals */
  42.  
  43. static EventRecord    evt;
  44. static Boolean        in_foreground = TRUE;
  45.  
  46. static Boolean        program_finished = FALSE;
  47.  
  48. static INTEGER pref_file;
  49. static Boolean pref_file_valid = FALSE;
  50.  
  51. /*--------------------------------------------------------------------*/
  52.  
  53. /* Local Prototypes */
  54.  
  55. static void handle_mouseDown(void);
  56. static void handle_mf_event(void);
  57.  
  58. static void start_up(void);
  59. static void shut_down(void);
  60.  
  61. /*--------------------------------------------------------------------*/
  62.  
  63. static pascal void sys_error_resume(void)
  64. /* Resume routine for system error. Just exits, but is better than 
  65.    forcing users to reboot. */
  66. {
  67.     ExitToShell();
  68. }
  69.  
  70. static void tool_box_init(void)
  71. /* General initialization calls.  Called at the beginning of the program. */
  72. {
  73.     InitGraf(&thePort);
  74.     InitFonts();
  75.     FlushEvents(everyEvent, 0);    /* Remove all events */
  76.     InitWindows();
  77.     InitMenus();
  78.     TEInit();
  79.     InitDialogs(sys_error_resume);
  80.     InitCursor();
  81. }
  82.  
  83. /*--------------------------------------------------------------------*/
  84.  
  85. static void process_arg_files(void)
  86. /* Process the file supplied when opening the application. */
  87. {
  88.     INTEGER message;
  89.     INTEGER count;
  90.     
  91.     CountAppFiles(&message, &count);
  92.     
  93.     if (count > 0) {
  94.         INTEGER index;
  95.         
  96.         if (message != appOpen)
  97.             ExitToShell();
  98.  
  99.         for (index = 1; index <= count; index++) {
  100.             AppFile info;
  101.             
  102.             GetAppFiles(index, &info);
  103.             if (info.fType == SAVE_FILE_SIGNATURE)
  104.                 game_load(info.fName, info.vRefNum);
  105.             ClrAppFiles(index);
  106.         }
  107.     }
  108. }
  109.  
  110.  
  111. /*--------------------------------------------------------------------*/
  112.  
  113. void main(void)
  114. /* The main function. Includes the main event loop. */
  115. {
  116.     Boolean WNE_implemented = FALSE;
  117.     
  118.     /* Initialization */
  119.     
  120.     tool_box_init();
  121.     
  122.     if (menu_init())
  123.         alert_fatal(1);
  124.     if (game_init())
  125.         alert_fatal(2);
  126.     if (highscore_init())
  127.         alert_fatal(3);        
  128.     if (controls_init())
  129.         alert_fatal(4);
  130.     
  131.     WNE_implemented = env_WaitNextEvent_available();
  132.     GetDateTime(&randSeed);    /* Initialize random number seed */
  133.     
  134.     game_new();
  135.     process_arg_files();
  136.  
  137.     start_up();
  138.     
  139.     /* Main event loop */
  140.     
  141.     while (! program_finished) {
  142.         if (WNE_implemented)
  143.             WaitNextEvent(everyEvent, &evt, 0L, NIL);
  144.         else {
  145.             SystemTask();
  146.             GetNextEvent(everyEvent, &evt);
  147.         }
  148.         
  149.         switch (evt.what) {
  150.         case mouseDown:
  151.             handle_mouseDown();
  152.             break;
  153.         case mouseUp:
  154.             /* ignored */
  155.             break;
  156.         case autoKey:
  157.         case keyDown:            
  158.             if (evt.modifiers & cmdKey) {
  159.                 adjust_menus();
  160.                 program_finished = menu_choice(MenuKey(evt.message &
  161.                                                        charCodeMask));
  162.             }
  163.             else {
  164.                 register WindowPtr wind = FrontWindow();
  165.                 
  166.                 if (wind && ! is_DA_window(wind))
  167.                     window_key(wind, (evt.message & keyCodeMask) >> 8,
  168.                                evt.message & charCodeMask);
  169.             }
  170.             break;
  171.         case updateEvt:
  172.             window_update((WindowPtr) evt.message);
  173.             break;
  174.         case activateEvt:
  175.             if (evt.modifiers & activeFlag)
  176.                 window_activate((WindowPtr) evt.message);
  177.             else
  178.                 window_deactivate((WindowPtr) evt.message);
  179.             break;
  180.         case osEvt:
  181.             handle_mf_event();
  182.             break;
  183.         }
  184.         
  185.         game_periodic();
  186.     }
  187.     
  188.     shut_down();
  189.     
  190.     game_term();
  191.     highscore_term();
  192.     
  193.     ExitToShell();
  194. }
  195.  
  196. /*--------------------------------------------------------------------*/
  197.  
  198. static void handle_mouseDown(void)
  199. /* Handles mouseDown events from the main event loop. Dispatches them
  200.    to the appropriate handler. */
  201. {
  202.     WindowPtr    wind;
  203.  
  204.     switch (FindWindow(evt.where, &wind)) {
  205.     case inDesk:
  206.         /* ignore */
  207.         break;
  208.     case inMenuBar:
  209.         adjust_menus ();
  210.         program_finished = menu_choice(MenuSelect(evt.where));
  211.         break;
  212.     case inSysWindow:
  213.         SystemClick(&evt, wind);
  214.         break;
  215.     case inContent:
  216.         if (FrontWindow() == wind)
  217.             window_mouseDown(wind, evt.where);
  218.         else
  219.             SelectWindow(wind);
  220.         break;
  221.     case inDrag:
  222.         DragWindow(wind, evt.where, &((*GrayRgn)->rgnBBox));
  223.     case inGrow:
  224.         break;
  225.     case inGoAway:
  226.         program_finished = TrackGoAway(wind, evt.where);
  227.         break;
  228.     default:
  229.         /* Should not get here */
  230.         SysBeep(5);
  231.         break;
  232.     }
  233. }
  234.  
  235. /*--------------------------------------------------------------------*/
  236.  
  237. static void handle_mf_event(void)
  238. /* Handles the multifinder events. */
  239. {
  240.     register unsigned char type = (evt.message & osEvtMessageMask) >> 24;
  241.     
  242.     switch (type) {
  243.       case suspendResumeMessage:
  244.           if (evt.message & resumeFlag) {
  245.               /* Resume */
  246.               register WindowPtr front = FrontWindow();
  247.               
  248.               if (! is_DA_window(front))
  249.                 window_activate(front);
  250.               in_foreground = TRUE;
  251.           }
  252.           else {
  253.               /* Suspend */
  254.               register WindowPtr front = FrontWindow();
  255.               
  256.               if (! is_DA_window(front))
  257.                 window_deactivate(front);
  258.               in_foreground = FALSE;
  259.           }
  260.           break;
  261.     case mouseMovedMessage:
  262.         /* Ignore */
  263.         break;
  264.     }
  265. }
  266.  
  267. /*--------------------------------------------------------------------*/
  268.  
  269. static Boolean option_key_pressed(void)
  270. /* Determines if the option key is pressed.  Returns true if it is. */
  271. {
  272.     static const k_option = 58;
  273.     unsigned char map[16];
  274.     
  275.     GetKeys(&map);
  276.     
  277.     if ((map[k_option >> 3] >> (k_option & 7)) & 1) 
  278.         return TRUE;
  279.     else 
  280.         return FALSE;
  281. }
  282.  
  283. /*--------------------------------------------------------------------*/
  284.  
  285. static void start_up(void)
  286. /* Opens the preference file, and loads up the information from it. */
  287. {
  288.     register OSErr erc;
  289.     
  290.     erc = pref_open(&pref_file, PREF_FILE_STR_ID,
  291.                     CREATOR_SIGNATURE, PREF_FILE_SIGNATURE, FALSE);
  292.     if (erc == noErr) {
  293.         pref_file_valid = TRUE;
  294.         if (high_score_load())
  295.             alert_caution(1);
  296.         controls_load();
  297.         game_load_location();
  298.         highscore_load_location();
  299.     }
  300.     
  301.     game_begin();
  302. }
  303.  
  304. /*--------------------------------------------------------------------*/
  305.  
  306. static void shut_down(void)
  307. /* Writes out information to the preference file (creating one if it
  308.    did not exist). */
  309. {
  310.     register OSErr erc;
  311.  
  312.     if (! pref_file_valid) {
  313.         erc = pref_open(&pref_file, PREF_FILE_STR_ID,
  314.                         CREATOR_SIGNATURE, PREF_FILE_SIGNATURE, TRUE);
  315.         if (erc == noErr)
  316.             pref_file_valid = TRUE;
  317.         else {
  318.             StringHandle sh = GetString(PREF_FILE_STR_ID);
  319.             
  320.             HLock(sh);
  321.             ParamText(*sh, 0, 0, 0);
  322.             alert_erc(2, erc);
  323.             HUnlock(sh);
  324.         }
  325.     }
  326.     
  327.     /* Write out preference information */
  328.     
  329.     if (pref_file_valid) {
  330.         erc = high_score_save(pref_file);
  331.         if (erc != noErr)
  332.             alert_erc(6, erc);
  333.         erc = controls_save(pref_file);
  334.         if (erc != noErr)
  335.             alert_erc(6, erc);
  336.         erc = game_save_location(pref_file);
  337.         if (erc != noErr)
  338.             alert_erc(6, erc);
  339.         erc = highscore_save_location(pref_file);
  340.         if (erc != noErr)
  341.             alert_erc(6, erc);
  342.     }
  343.     
  344.     /* Close the preference file */
  345.     
  346.     if (pref_file_valid) {
  347.         CloseResFile(pref_file);
  348.         erc = ResError();
  349.         if (erc != noErr) {
  350.             StringHandle sh = GetString(PREF_FILE_STR_ID);
  351.             
  352.             HLock(sh);
  353.             ParamText(*sh, 0, 0, 0);
  354.             alert_erc(5, erc);
  355.             HUnlock(sh);
  356.         }        
  357.         pref_file_valid = FALSE;
  358.     }
  359. }
  360.  
  361. /*--------------------------------------------------------------------*/
  362.